package com.shangjinrong.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shangjinrong.domain.Dict;
import com.shangjinrong.domain.dto.ExcelDictDto;
import com.shangjinrong.listener.ExcelDictDtoListener;
import com.shangjinrong.mapper.DictMapper;
import com.shangjinrong.service.DictService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Naruto
 */
@Service
@Slf4j
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {


    @Resource
    private DictMapper dictMapper;

    @Resource
    private RedisTemplate redisTemplate;


    @Override
    public List<Dict> listByParentId(String parentId) {


        try {
            //从redis中查询是否存在数据列表
            List<Dict> dicts = (List<Dict>) redisTemplate.opsForValue().get("sjr:core:dictList" + parentId);
            if (dicts != null) {
                log.info("从redis中取出数据");
                return dicts;
            }
            //存在则从redis中读取
        }catch (Exception e){
            log.error("redis服务器异常");
        }

        //不存在查询数据库
        log.info("从数据库中取出数据 ");
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        List<Dict> dictList = baseMapper.selectList(queryWrapper);
        //填充hashChildren字段

        dictList.forEach(dist -> {
            //判断当前节点是否有子节点，找到当前的dict下级有没有子节点
            boolean hasChildren = hasChildren(dist.getId());
            dist.setHasChildren(hasChildren);
        });

        try {
            log.info("将数据存入redis");
            //将数据存入redis
            redisTemplate.opsForValue().set("sjr:core:dictList"+parentId,dictList,5, TimeUnit.MINUTES);
        }catch (Exception e){
            log.error("redis服务器异常");
        }

        return dictList;
    }

    /**
     * 判断当前id所在的节点下是否有子节点
     *
     * @param id
     * @return
     */
    private boolean hasChildren(Long id) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        Integer count = Math.toIntExact(baseMapper.selectCount(queryWrapper));

        return count > 0;
    }

    /**
     * @param inputStream 从前台传过来的excel表
     * @Transactional：事务，一旦出现Exception，则rollback
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importData(InputStream inputStream) {
        EasyExcel.read(inputStream, ExcelDictDto.class, new ExcelDictDtoListener(dictMapper))
                .sheet()
                .doRead();

        log.info("Excel导入成功");
    }

    @Override
    public List<ExcelDictDto> listDictData() {
        List<Dict> dictList = dictMapper.selectList(null);

        //创建ExcelDictDto列表，将Dict对象转换为ExcelDictDto对象
        List<ExcelDictDto> excelDictList = new ArrayList<>(dictList.size());

        //遍历集合，将dictList中的每个对象copy到新的对象，然后add到ExcelDictDto集合中
        for (Dict dict : dictList) {
            ExcelDictDto excelDictDto = new ExcelDictDto();
            BeanUtils.copyProperties(dict, excelDictDto);
            excelDictList.add(excelDictDto);
        }

        return excelDictList;
    }

    @Override
    public String getNameByParentDictCodeAndValue(String dictCode, Integer value) {
        QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();

        dictQueryWrapper.eq("dict_code", dictCode);

        Dict parentDict = baseMapper.selectOne(dictQueryWrapper);

        if (parentDict == null) {
            return "";
        }

        QueryWrapper<Dict> dictQueryWrapper1 = new QueryWrapper<>();

        dictQueryWrapper1
                .eq("parent_id", parentDict.getId())
                .eq("value", value);

        Dict dict = baseMapper.selectOne(dictQueryWrapper1);

        if (dict == null) {
            return "";
        }

        return dict.getName();


    }

    @Override
    public List<Dict> findDictByCode(String code) {
        LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Dict::getDictCode,code);
        Dict dict = baseMapper.selectOne(wrapper);
        return this.listByParentId(dict.getId().toString());
    }
}
